
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Sim3D_practicum.Physics;


namespace Sim3D_practicum.Components
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Lightbulb : Microsoft.Xna.Framework.DrawableGameComponent
    {
        private Vector3 Position;
        private Vector3 AttachPoint;
        public const float RADIUS = 20f;
        private const float RopeLength = 300f;
        private Color colour;
        private float speed = 1;
        private float acceleration = 1f;
        private float currentAngle = 0f;
        public Lightbulb(Vector3 AttachmentPoint, Game game)
            : base(game)
        {
            this.AttachPoint = AttachmentPoint;
            this.Position = Vector3.Add(AttachPoint, new Vector3(0, RopeLength, 0));
            colour = new Color(255, 255, 255);
        }

        /// <summary>
        /// Here, we hit the light with our queu, and make it move in direction d. It will also be rotating, as it is attached to the roof with a rope, 
        /// so the point where it is attached is the center of the rotation.
        /// </summary>
        /// <param name="q">the position and velocity where we hit the light and with what power</param>
        public void HitThat( Vector3 q )
        { 
            //Matrix.CreateTranslation( )
        }

        /// <summary>
        /// Rotate the light bulb around the cable it is attached to
        /// </summary>
        /// <param name="angleX">the angle the bulb will rotate around in the x direction</param>
        /// <param name="angleZ">the angle the bulb will rotate around in the y direction</param>
        private void RotateAroundCable( float angleX, float angleZ )
        {

        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize( )
        {
            // TODO: Add your initialization code here

            base.Initialize( );
        }

        static Texture2D art;
        private Rectangle scaledPosition;
        protected override void LoadContent()
        {
            if (art == null)
                art = Game.Content.Load<Texture2D>("Ball");
            base.LoadContent();
        }

        public void Draw(GameTime gameTime, SpriteBatch sprite)
        {

            sprite.Begin();
            scaledPosition.X = Calculator.mmToPixel(Position.X - RADIUS);
            scaledPosition.Y = Calculator.mmToPixel(Position.Z - RADIUS);
            scaledPosition.Width = Calculator.mmToPixel(RADIUS * 2);
            scaledPosition.Height = Calculator.mmToPixel(RADIUS * 2);
            sprite.Draw(art, scaledPosition, colour);

            sprite.End();
            base.Draw(gameTime);
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update( GameTime gameTime )
        {
            /* Rotation, assuming X doesn't change:
             * [1,0,0]
             * [0,cos,-sin]
             * [0,sin,cos]
             */
            //double angle = speed * gameTime.ElapsedGameTime.Milliseconds / 1000f;
            //Position = AttachPoint.
            if(currentAngle <= 0 )
                speed += acceleration * gameTime.ElapsedGameTime.Milliseconds / 1000f;
            else
                speed -= acceleration * gameTime.ElapsedGameTime.Milliseconds / 1000f;
            currentAngle += speed * gameTime.ElapsedGameTime.Milliseconds / 1000f;
            float sin = (float)Math.Sin(currentAngle);
            float cos = (float)Math.Cos(currentAngle);
            Matrix translateRope = new Matrix(1, 0, 0, 0,
                                  0, 1, 0, 0,
                                  0, 0, 1, 0,
                                  0, RopeLength, 0, 1);
            Matrix r = new Matrix(1, 0, 0, 0,
                                  0, cos, sin, 0,
                                  0, -sin, cos, 0,
                                  0, 0, 0, 1);
            Matrix translateAttach = new Matrix(1, 0, 0, 0,
                                  0, 1, 0, 0,
                                  0, -0, 1, 0,
                                  AttachPoint.X, AttachPoint.Y, AttachPoint.Z, 1);
            //apperantly, it takes the last matrix first
            Matrix m = translateRope * r * translateAttach;
            Position = m.Translation;
            base.Update( gameTime );
        }
    }
}